package com.example.module_mine.widget

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.FrameLayout
import com.example.lib_common.base.utils.ToastUtils
import com.example.module_mine.R


/**
 *@author Wcj
 *@description 短信验证码
 *@date 2022/6/25 13:22
 */
class VerifyCodeView : FrameLayout, View.OnClickListener {

    private val codeViewList: List<VerifyCodeItemView>
    private val et: EditText
    private lateinit var tvPaste: View
    private var inputText = ""
    private var codeLength = 0
    private var onInputVerifyCodeCompleted: ((smsCode: String) -> Unit)? = null

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        val parentView = LayoutInflater.from(context).inflate(R.layout.layout_verify_code_view, this) as ViewGroup
        codeViewList = listOf(
            parentView.findViewById(R.id.code_1),
            parentView.findViewById(R.id.code_2),
            parentView.findViewById(R.id.code_3),
            parentView.findViewById(R.id.code_4),
            parentView.findViewById(R.id.code_5),
            parentView.findViewById(R.id.code_6)
        )
        codeLength = codeViewList.size
        parentView.setOnClickListener(this)
        tvPaste = parentView.findViewById<View>(R.id.tv_paste)
        tvPaste.setOnClickListener {
            paste()
            tvPaste.visibility = View.GONE
        }
        parentView.setOnLongClickListener {
            if (tvPaste.visibility == View.VISIBLE) {
                tvPaste.visibility = View.GONE
            } else {
                tvPaste.visibility = View.VISIBLE
            }

            true
        }
        et = parentView.findViewById(R.id.et_input)
        et.setOnFocusChangeListener { _, b ->

            if (b) {
                if (inputText.length < codeViewList.size) {
                    codeViewList[inputText.length].setFocus(true)
                }
            } else {
                codeViewList.forEach {
                    it.setFocus(false)
                }
            }
        }
        et.setOnEditorActionListener { _, i, _ ->
            if (i == EditorInfo.IME_ACTION_DONE) {
                hideSoftKeyBoard()
                this.onInputVerifyCodeCompleted?.invoke(inputText)
            }
            true
        }
        et.addTextChangedListener(VerifyCodeTextWatcher())
    }

    private fun paste() {
        val code = getClipData()
        //校验验证码长度
        if (code?.length == 6) {
            et.setText("")
            et.setText(getClipData())
        } else {
            ToastUtils.showShort(context, "粘贴内容错误")
        }
    }

    fun hidePaste() {
        if (tvPaste.visibility == View.VISIBLE) {
            tvPaste.visibility = View.GONE
        }
    }


    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        codeViewList.forEach {
            it.setFocus(false)
        }
    }


    fun showSoftKeyBoard() {
        val manager: InputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        postDelayed({
            et.requestFocus()
            manager.showSoftInput(et, InputMethodManager.RESULT_UNCHANGED_SHOWN)
        }, 300)
    }

    private fun hideSoftKeyBoard() {
        et.clearFocus()
        val manager: InputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        manager.hideSoftInputFromWindow(this.windowToken, 0)
    }


    override fun onClick(v: View?) {
        et.requestFocus()
        showSoftKeyBoard()
        tvPaste.visibility = View.GONE

    }

    fun clear() {
        et.text.clear()
    }

    private fun getClipData(): String? {
        //获取系统剪贴板服务
        val clipboardManager: ClipboardManager? = context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
        if (null != clipboardManager) {
            // 获取剪贴板的剪贴数据集
            val clipData: ClipData? = clipboardManager.getPrimaryClip()
            if (null != clipData && clipData.getItemCount() > 0) {
                // 从数据集中获取（粘贴）第一条文本数据
                val item: ClipData.Item = clipData.getItemAt(0)
                if (null != item) {
                    return item.getText().toString()
                }
            }
        }
        return null
    }

    fun setOnInputVerifyCodeCompleted(l: (smsCode: String) -> Unit) {
        this.onInputVerifyCodeCompleted = l
    }

    inner class VerifyCodeTextWatcher : TextWatcher {
        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }

        override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            tvPaste.visibility = View.GONE
            //当前输入的内容
            inputText = p0?.toString() ?: ""
            //p2 一次删除的长度 只能通过键盘删除始终为 1或0
            //p3 一次增加的数据长度
            if (p2 == 0) {
                //焦点前移
                if (inputText.length < codeViewList.size)
                    codeViewList[inputText.length].setFocus(true)
                //取消后位的焦点
                if (inputText.isNotEmpty()) {
                    codeViewList[inputText.length - p3].setFocus(false)
                }
                //设置输入的内容
                repeat(inputText.length) {
                    codeViewList[it].setNumber(inputText[it].toString())
                }

            } else {
                //焦点后移
                if (inputText.length >= 6) return
                codeViewList[inputText.length].setFocus(true)
                //取消前一位焦点
                if (inputText.length + p2 < codeViewList.size) {
                    codeViewList[inputText.length + p2].setFocus(false)

                }
                //清除输入内容
                repeat(p2) {
                    codeViewList[inputText.length + it].setNumber("")
                }
            }
            if (inputText.length == codeLength) {
                //自动触发输入完成
                hideSoftKeyBoard()
                this@VerifyCodeView.onInputVerifyCodeCompleted?.invoke(inputText)
            }
        }

        override fun afterTextChanged(p0: Editable?) {

        }

    }

}